return Ok(());
}
- registry.publish(&NewCrate {
+ let publish = registry.publish(&NewCrate {
name: pkg.name().to_string(),
vers: pkg.version().to_string(),
deps: deps,
repository: repository.clone(),
license: license.clone(),
license_file: license_file.clone(),
- }, tarball).map_err(|e| {
- human(e.to_string())
- })
+ }, tarball);
+
+ match publish {
+ Ok(invalid_categories) => {
+ if !invalid_categories.is_empty() {
+ let msg = format!("\
+ the following are not valid category slugs and were \
+ ignored: {}. Please see https://crates.io/category_slugs \
+ for the list of all category slugs. \
+ ", invalid_categories.join(", "));
+ config.shell().warn(&msg)?;
+ }
+ Ok(())
+ },
+ Err(e) => Err(human(e.to_string())),
+ }
}
pub fn registry_configuration(config: &Config) -> CargoResult<RegistryConfig> {
use std::result;
use curl::easy::{Easy, List};
-use rustc_serialize::json;
+use rustc_serialize::json::{self, Json};
use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET};
NotFound,
JsonEncodeError(json::EncoderError),
JsonDecodeError(json::DecoderError),
+ JsonParseError(json::ParserError),
}
impl From<json::EncoderError> for Error {
}
}
+impl From<json::ParserError> for Error {
+ fn from(err: json::ParserError) -> Error {
+ Error::JsonParseError(err)
+ }
+}
+
impl From<curl::Error> for Error {
fn from(err: curl::Error) -> Error {
Error::Curl(err)
#[derive(RustcDecodable)] struct Users { users: Vec<User> }
#[derive(RustcDecodable)] struct TotalCrates { total: u32 }
#[derive(RustcDecodable)] struct Crates { crates: Vec<Crate>, meta: TotalCrates }
-
impl Registry {
pub fn new(host: String, token: Option<String>) -> Registry {
Registry::new_handle(host, token, Easy::new())
Ok(json::decode::<Users>(&body)?.users)
}
- pub fn publish(&mut self, krate: &NewCrate, tarball: &File) -> Result<()> {
+ pub fn publish(&mut self, krate: &NewCrate, tarball: &File)
+ -> Result<Vec<String>> {
let json = json::encode(krate)?;
// Prepare the body. The format of the upload request is:
//
headers.append(&format!("Authorization: {}", token))?;
self.handle.http_headers(headers)?;
- let _body = handle(&mut self.handle, &mut |buf| {
+ let body = handle(&mut self.handle, &mut |buf| {
body.read(buf).unwrap_or(0)
})?;
- Ok(())
+ // Can't derive RustcDecodable because JSON has a key named "crate" :(
+ let response = Json::from_str(&body)?;
+ let invalid_categories: Vec<String> =
+ response
+ .find_path(&["warnings", "invalid_categories"])
+ .and_then(Json::as_array)
+ .map(|x| {
+ x.iter().flat_map(Json::as_string).map(Into::into).collect()
+ })
+ .unwrap_or_else(Vec::new);
+ Ok(invalid_categories)
}
pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec<Crate>, u32)> {
Error::NotFound => write!(f, "cannot find crate"),
Error::JsonEncodeError(ref e) => write!(f, "json encode error: {}", e),
Error::JsonDecodeError(ref e) => write!(f, "json decode error: {}", e),
+ Error::JsonParseError(ref e) => write!(f, "json parse error: {}", e),
}
}
}